package gang.org.springframework.framework.core;

import gang.org.springframework.framework.support.GangMethodParameter;

import java.io.Serializable;
import java.lang.reflect.Type;

/**
 * @author gang.chen
 * @description
 * @Date 2021/12/8 13:19
 */
final public class GangSerializableTypeWrapper {


    public interface GangTypeProvider extends Serializable{

        /**
         * type is supper interface of any class
         * @return Result actual Class
         */
        Type getType();

        /**
         * return the source of type, or null if not known
         * @return Object
         */
        default Object getSource()
        {
            return null;
        }
    }

    public static class GangMethodParameterTypeProvider implements GangTypeProvider{

        private final String methodName;

        private final Class<?>[] parameterTypes;

        private final Class<?> declaringClass;

        private final int parameterIndex;

        private transient GangMethodParameter methodParameter;

        public GangMethodParameterTypeProvider(GangMethodParameter methodParameter){
            this.methodName = methodParameter.getMethod() != null ? methodParameter.getMethod().getName():null;
            this.parameterTypes = methodParameter.getMethod().getParameterTypes();
            this.declaringClass = methodParameter.getDeclaringClass();
            this.parameterIndex = methodParameter.getParameterIndex();
            this.methodParameter = methodParameter;
        }

        @Override
        public Type getType() {
            return this.methodParameter.getGenericParameterType();
        }

        @Override
        public Object getSource() {
            return GangTypeProvider.super.getSource();
        }
    }

    /**
     * 业务意义
     * 1）方法返回实体类
     * 2）mvcResourceUrlProvider bean名称"mvcResourceUrlProvider"，返回实体类：“gang.org.springframework.framework.resource.GangResourceUrlProvider”
     * */
    public static Type forTypeProvider(GangTypeProvider provider){
        Type providerType = provider.getType();
        if (providerType == null || providerType instanceof Serializable) {
            return providerType;
        }
        return null;
    }
}
